home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 2 / LSD and 17bit Compendium Deluxe - Volume II.iso / a / prog / asmsrc / imploderdecr.lha / Impl.s
Encoding:
Text File  |  1993-09-26  |  8.0 KB  |  418 lines

  1.  
  2.                 * Imploder Style Decrunch by Cath of LSD *
  3.                 * Taken from the depths of IEEE magazine *
  4.  
  5.                   * SProModule was extended from here ! *
  6.  
  7. * Tester!
  8.  
  9.     ifne    0
  10.     lea    Data(pc),a0
  11.     lea    buffer(pc),a1
  12.     bsr    IMPL_Decr
  13.     clr.l    d0
  14.     rts
  15.  
  16.     endc
  17.  
  18. ID    equ    'IMP!'        ; ID suggested by ieee and used by a cruncher?
  19.  
  20.        * IMP! Scrunch Pro (SPMO) Module Decruncher by Cath of LsD *
  21.  
  22.  
  23.     STRUCTURE SProModule,0
  24.     ULONG    sm_CrunchedAddr        ; The address of the crunched data
  25.     ULONG    sm_CrunchedSize        ; The size of the crunched data
  26.     ULONG    sm_DecrAddr    ; This is used by the module to pass back data
  27.     ULONG    sm_DecrSize    ; This is used by the module to pass back data
  28.     ULONG    sm_Reserved1    ; Guess (For future use, currently set to zero)
  29.     ULONG    sm_Reserved2    ; Guess (For future use, currently set to zero)
  30.     ULONG    sm_Informer    ; This is set to the addrress to shove data to
  31.                 ; ie _custom.color00
  32.  
  33.     LABEL    spro_SIZEOF
  34.  
  35. ;    Anything beyond this is currently private!
  36.  
  37. ;    ............X         ; Private data
  38.  
  39.  
  40. SM_NOMEMORY    equ    $DEADFFF0    ; no memory for crunch/decrunch
  41. SM_UNRECOGNISED    equ    $DEADFFF1    ; not a recognised buffer
  42. SM_UNKNOWN    equ    $DEADFFF2    ; unknown error
  43. SM_NODECRUNCH    equ    $DEADFFF3    ; this module is crunch only
  44. SM_NOCRUNCH    equ    $DEADFFF4    ; this module is decrunch only
  45. SM_COULDNTCRUNCH equ    $DEADFFF5    ; actual cruncher couldn't decrunch ?
  46. SM_COULDNTDECR equ    $DEADFFF6    ; actual decruncher couldn't crunch
  47.  
  48.     dc.b    'SPMO'    ; The third sprmo decr module
  49.  
  50. Start
  51.     tst.l    sm_DecrAddr(a0)            ; Is this a DeCrunch ?
  52.     beq.s    DeCrunch            ; Yes
  53.  
  54.     ; This is no cruncher, baby!
  55.  
  56. NoCruncher
  57.     move.l    #-1,sm_DecrAddr(a0)    ; Tell scrunch about the error
  58.     move.l    #SM_NOCRUNCH,sm_DecrSize(a0)    ; No crunch possible
  59.     rts
  60.  
  61. DeCrunch
  62.     move.l    (a0),a1            ; Get address of crunched data
  63.     cmp.l    #ID,(a1)        ; Is this valid data
  64.     beq.s    YesValidData        ; Yes its Ok
  65.  
  66.     move.l    #-1,sm_DecrAddr(a0)    ; Tell scrunch about error
  67.     move.l    #SM_UNRECOGNISED,sm_DecrSize(a0)    ; Error code
  68.     rts
  69.         
  70. YesValidData
  71.  
  72.     move.l    4(a1),sm_DecrSize(a0)    ; Get size of decrunched data
  73.     move.l    4.w,a6
  74.     movem.l    a0/a1,-(sp)
  75.     move.l    4(a1),d0        ; Get size of decrunched data
  76.     move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1;  Mem flags
  77.     jsr    _LVOAllocMem(a6)    ; Allocate mem
  78.     movem.l (sp)+,a0/a1        ; Restore regs
  79.     tst.l    d0
  80.     bne.s    MemOk            ; Allocated Ok,
  81.  
  82.     ; Not enough memory for decrunch !
  83.  
  84.     move.l    #-1,sm_DecrAddr(a0)
  85.     move.l    #SM_NOMEMORY,sm_DecrSize(a0)
  86.     rts
  87.  
  88. MemOk
  89.     move.l    d0,sm_DecrAddr(a0)    ; Set address of decrunched data
  90.                     ; sm_DecrSize has already been set
  91.  
  92.     movem.l    a0-a6/d1-d7,-(sp)    ; Save all regs!
  93.  
  94.     move.l    sm_DecrAddr(a0),a1    ; Set decrunch address
  95.     move.l    sm_CrunchedAddr(a0),a0    ; Set crunched address (doesn't need offset)
  96.                     ; no point removing as its negligble)
  97.  
  98. * This decruncher requires the crunched buffer to be in the deCrunch buffer
  99. * so we need to move the original crunched data
  100.  
  101. * +---------------------------------Decrunch Mem area -------------+
  102. * +-----------Crunched Data ------+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+
  103. *                                  ^ filled in by decruncher
  104.  
  105.     movem.l    a0-a6/d0-d7,-(sp)
  106.  
  107.     move.l    8(a0),d0        ; Get size of crunched data
  108.     add.l    #80,d0            ; And a bit more for luck (to cover table)
  109.     move.l    4.w,a6            ; Execbase
  110.     jsr    _LVOCopyMemQuick(a6)    ; Copymem
  111.  
  112.     movem.l    (sp)+,a0-a6/d0-d7
  113.  
  114.     move.l    a1,a0            ; Set both addresses to same area
  115.  
  116.     bsr.s    IMPL_Decr        ; Decrunch the Data
  117.     movem.l    (sp)+,a0-a6/d1-d7    ; Ok
  118.  
  119.     beq.s    DecrError        ; There was an error!
  120.  
  121.     rts                ; Return to Scrunch Ok!
  122.  
  123. DecrError
  124.     move.l    sm_DecrAddr(a0),a1    ; An error in the decrunch
  125.     move.l    sm_DecrSize(a0),d0
  126.     move.l    4.w,a6
  127.     move.l    a0,-(sp)
  128.     jsr    _LVOFreeMem(a6)        ; So free the memory
  129.     move.l    (sp)+,a0
  130.  
  131.     move.l    #-1,sm_DecrAddr(a0)
  132.     move.l    #SM_COULDNTDECR,sm_DecrSize(a0)    ; Tell scrunch about the error
  133.     rts
  134.  
  135.  
  136.     ; this is the actual decruncher
  137.  
  138. Leave
  139.     moveq    #0,d0            ; setup bad ret code
  140.     rts
  141.  
  142. IMPL_Decr *******************************
  143. * A0-ptr to buffer,A0 ptr to out buffer *
  144. *****************************************
  145.  
  146. * Taken from the depths of IEEE magazine
  147. * This is basically the same routine as imploder uses (its where it gets its name from, the
  148. * program not the algorithm and its used widely). Its based on LZW compression
  149. * this is the basis on which AT&T and BT based their own compression systems on
  150. * other programs that use it are lha and pkware
  151.  
  152. Decompress
  153.     cmp.l    #ID,(a0)        ; Check imploder header string
  154.                     ; this is the ISO/IEEE string used
  155.     bne.s    Leave
  156.  
  157.     movem.l    d2-d5/a2-a5,-(sp)    ; save blasted regs
  158.  
  159.     move.l    a0,a3            ; get copy of buffer ptr
  160.     move.l    a0,a5            ; get copy of destination buffer ptr
  161.  
  162.     tst.l    (a0)+            ; Skip IMP! ID
  163.  
  164.     add.l    (a0)+,a5        ; Get decrunched length
  165.  
  166.     add.l    (a0)+,a3        ; Get crunched length
  167.  
  168.     move.l    a3,a2            ; A2->End of crunched buffer
  169.                     ; A5->End of Complete buffer
  170.  
  171.     move.l    (a2)+,-(a0)        ; Get data table
  172.     move.l    (a2)+,-(a0)
  173.     move.l    (a2)+,-(a0)
  174.     move.l    (a2)+,d2
  175.     move.w    (a2)+,d3
  176.  
  177.     bmi.s    DontFix
  178.  
  179.     subq.l    #1,a3            ; Ptr to Buffer End - 1 
  180.  
  181. DontFix
  182.  
  183.     lea    -$1C(sp),sp        ; Get some stack space
  184.  
  185.     move.l    sp,a1            ; point to it
  186.  
  187.     moveq    #6,d0            ; rest of table
  188. MoveTable
  189.     move.l    (a2)+,(a1)+
  190.     dbra    d0,MoveTable
  191.  
  192.     move.l    sp,a1            ; point to source again
  193.  
  194. StartDecr
  195.     tst.l    d2            ; Anything to store ?
  196.     beq.s    Nope            ; No
  197.  
  198. CopyLoop
  199.     move.b    -(a3),-(a5)        ; Store decrunched data
  200.     subq.l    #1,d2            ; Decrement byte count
  201.     bne.s    CopyLoop        ; Any more to do 
  202.  
  203. Nope
  204.     cmp.l    a5,a0            ; Have we reached begininng of buffer
  205.     bcs.s    DoDecrunch        ; Still to decrunch
  206.  
  207.  
  208.     lea    $1C(sp),sp        ; free stack space
  209.  
  210.     moveq    #-1,d0            ; Set return code as good
  211.  
  212.     cmp.l    a3,a0            ; Do the end addresses match? 
  213.     beq.s    MatchOk
  214.  
  215.     moveq    #0,d0            ; Set return code as bad
  216.  
  217. MatchOk
  218.     movem.l    (sp)+,d2-d5/a2-a5
  219.     tst.l    d0            ; Save returned prog checking
  220.     rts                ; Return code
  221.  
  222.  
  223. DoDecrunch
  224.     add.b    d3,d3            ; doubler
  225.     bne.s    DOA
  226.     move.b    -(a3),d3
  227.     addx.b    d3,d3
  228.  
  229. DOA
  230.     bcc.s    SetupDecodeTable_4
  231.     add.b    d3,d3
  232.     bne.s    Extract_1
  233.     move.b    -(a3),d3
  234.     addx.b    d3,d3
  235.  
  236. Extract_1
  237.     bcc.s    SetupDecodeTable_3
  238.     add.b    d3,d3
  239.     bne.s    Extract_2
  240.     move.b    -(a3),d3
  241.     addx.b    d3,d3
  242.  
  243. Extract_2
  244.     bcc.s    SetupDecodeTable_2
  245.     add.b    d3,d3
  246.     bne.s    Extract_3
  247.     move.b    -(a3),d3
  248.     addx.b    d3,d3
  249.  
  250. Extract_3
  251.     bcc.s    SetupDecodeTable_1
  252.     moveq    #0,d4
  253.     add.b    d3,d3
  254.     bne.s    Extract_4
  255.     move.b    -(a3),d3
  256.     addx.b    d3,d3
  257.  
  258. Extract_4
  259.     bcc.s    Extract_5
  260.     move.b    -(a3),d4
  261.     moveq    #3,d0
  262.     subq.b    #1,d4
  263.     bra.s    DecodeTable_1
  264.  
  265. Extract_5
  266.     add.b    d3,d3
  267.     bne.s    Extract_6
  268.     move.b    -(a3),d3
  269.     addx.b    d3,d3
  270.  
  271. Extract_6
  272.     addx.b    d4,d4
  273.     add.b    d3,d3
  274.     bne.s    Extract_7
  275.     move.b    -(a3),d3
  276.     addx.b    d3,d3
  277.  
  278. Extract_7
  279.     addx.b    d4,d4
  280.     add.b    d3,d3
  281.     bne.s    Extract_8
  282.     move.b    -(a3),d3
  283.     addx.b    d3,d3
  284.  
  285. Extract_8
  286.     addx.b    d4,d4
  287.     addq.b    #5,d4
  288.     moveq    #3,d0
  289.     bra.s    DecodeTable_1
  290.  
  291. SetupDecodeTable_1
  292.     moveq    #4,d4
  293.     moveq    #3,d0
  294.     bra.s    DecodeTable_1
  295.  
  296. SetupDecodeTable_2
  297.     moveq    #3,d4
  298.     moveq    #2,d0
  299.     bra.s    DecodeTable_1
  300.  
  301. SetupDecodeTable_3
  302.     moveq    #2,d4
  303.     moveq    #1,d0
  304.     bra.s    DecodeTable_1
  305.  
  306. SetupDecodeTable_4
  307.     moveq    #1,d4
  308.     moveq    #0,d0
  309.  
  310. DecodeTable_1
  311.     moveq    #0,d5
  312.     move.w    d0,d1
  313.     add.b    d3,d3
  314.     bne.s    NoFetch1
  315.     move.b    -(a3),d3
  316.     addx.b    d3,d3
  317.  
  318. NoFetch1
  319.     bcc.s    DoTable
  320.     add.b    d3,d3
  321.     bne.s    NoFetch2
  322.     move.b    -(a3),d3
  323.     addx.b    d3,d3
  324.  
  325. NoFetch2
  326.     bcc.s    NoEntry
  327.     move.b    ImpTable(pc,d0.w),d5
  328.     addq.b    #8,d0
  329.     bra.s    DoTable
  330.  
  331. NoEntry
  332.     moveq    #2,d5                ; Set default
  333.     addq.b    #4,d0
  334.  
  335. DoTable
  336.     move.b    RunTable(pc,d0.w),d0        ; ptr to run table
  337.  
  338. _DoTable
  339.     add.b    d3,d3
  340.     bne.s    NoFetch3
  341.     move.b    -(a3),d3
  342.     addx.b    d3,d3
  343.  
  344. NoFetch3
  345.     addx.w    d2,d2
  346.     subq.b    #1,d0
  347.     bne.s    _DoTable
  348.     add.w    d5,d2
  349.     moveq    #0,d5
  350.     move.l    d5,a2
  351.     move.w    d1,d0
  352.     add.b    d3,d3
  353.     bne.s    NoFetch4
  354.     move.b    -(a3),d3
  355.     addx.b    d3,d3
  356.  
  357. NoFetch4
  358.     bcc.s    NoFetch5
  359.     add.w    d1,d1
  360.     add.b    d3,d3
  361.     bne.s    NoFetch5a
  362.     move.b    -(a3),d3
  363.     addx.b    d3,d3
  364.  
  365. NoFetch5a
  366.     bcc.s    DoAgain
  367.  
  368.     move.w    8(a1,d1.w),a2
  369.     addq.b    #8,d0
  370.     bra.s    NoFetch5
  371.  
  372. DoAgain
  373.     move.w    (a1,d1.w),a2
  374.     addq.b    #4,d0
  375.  
  376. NoFetch5
  377.     move.b    16(a1,d0.w),d0
  378.  
  379. DoBytes
  380.     add.b    d3,d3
  381.     bne.s    NoFetch7
  382.     move.b    -(a3),d3
  383.     addx.b    d3,d3
  384.  
  385. NoFetch7
  386.     addx.l    d5,d5
  387.     subq.b    #1,d0
  388.     bne.s    DoBytes
  389.  
  390.     addq.w    #1,a2
  391.     add.l    d5,a2
  392.     add.l    a5,a2
  393.  
  394. CopyLoop2
  395.     move.b    -(a2),-(a5)            ; Store bytes
  396.     dbra    d4,CopyLoop2
  397.  
  398.     bra    StartDecr            ; Continue, and check for end
  399.  
  400.  
  401. * --------------- Data Area ------------- *
  402.  
  403. ImpTable
  404.     dc.b    6,10,10,18
  405.  
  406. RunTable
  407.     dc.b    1,1,1,1,2,3,3,4,4,5,7,14    ; Length of runs
  408.  
  409.     ifne    0
  410.  
  411. Data
  412.     incbin    spmo:test.impl
  413. buffer
  414.     dcb.b    500000,0
  415.     endc
  416.  
  417.     END
  418.